﻿using Infrastructure.Model.DI;
using Microsoft.AspNetCore.Components.Web;
using Minio.DataModel.Notification;
using Model.EntityModel.Auth;
using Model.ResultModel;
using Repository.IRepository.ISysRepository;

namespace Repository.Repository.SysRepository
{
    [AppService(ServiceType = typeof(IMenuRepository), ServiceLifetime = LifeTime.Transient)]
    public class MenuRepository : SqlSugarBaseRepository<Menu>, IMenuRepository
    {
        /// <summary>
        /// 修复的树形菜单获取方法
        /// </summary>
        public List<MenuResult> GetAllMenus()
        {
            var allMenus = base.Queryable().Where(item=>item.IsActive=="Y")
                .OrderBy(m => m.SortOrder)
                .ToList();

            // 创建ID映射字典
            var menuDict = allMenus.ToDictionary(m => m.Id);

            // 按父ID分组（包含ParentId=0的情况）
            var menuByParentId = allMenus
                .Where(m => m.ParentId.HasValue)
                .GroupBy(m => m.ParentId.Value)
                .ToDictionary(g => g.Key, g => g.OrderBy(m => m.SortOrder).ToList());

            // 使用栈代替递归防止溢出
            var result = new List<MenuResult>();
            var stack = new Stack<Menu>();

            // 推入顶级节点（ParentId=null 或 0）
            foreach (var menu in allMenus.Where(m =>
                !m.ParentId.HasValue || m.ParentId == 0))
            {
                stack.Push(menu);
            }

            while (stack.Count > 0)
            {
                var current = stack.Pop();
                var node = ConvertToResult(current);

                // 处理子节点
                if (menuByParentId.TryGetValue(current.Id, out var children))
                {
                    foreach (var child in children.OrderByDescending(c => c.SortOrder))
                    {
                        stack.Push(child);
                        node.children.Insert(0, ConvertToResult(child)); // 保持排序
                    }
                }

                // 添加到结果集
                if (current.ParentId == null || current.ParentId == 0)
                {
                    result.Add(node);
                }
            }

            return result.OrderBy(r => r.sortOrder).ToList();
        }
        public List<MenuResult> GetMenusList()
        {
            var allMenus = base.Queryable().OrderBy(m => m.SortOrder) .ToList();
            // 创建ID映射字典
            var menuDict = allMenus.ToDictionary(m => m.Id);

            // 按父ID分组（包含ParentId=0的情况）
            var menuByParentId = allMenus
                .Where(m => m.ParentId.HasValue)
                .GroupBy(m => m.ParentId.Value)
                .ToDictionary(g => g.Key, g => g.OrderBy(m => m.SortOrder).ToList());

            // 使用栈代替递归防止溢出
            var result = new List<MenuResult>();
            var stack = new Stack<Menu>();

            // 推入顶级节点（ParentId=null 或 0）
            foreach (var menu in allMenus.Where(m =>
                !m.ParentId.HasValue || m.ParentId == 0))
            {
                stack.Push(menu);
            }

            while (stack.Count > 0)
            {
                var current = stack.Pop();
                var node = ConvertToResult(current);

                // 处理子节点
                if (menuByParentId.TryGetValue(current.Id, out var children))
                {
                    foreach (var child in children.OrderByDescending(c => c.SortOrder))
                    {
                        stack.Push(child);
                        node.children.Insert(0, ConvertToResult(child)); // 保持排序
                    }
                }

                // 添加到结果集
                if (current.ParentId == null || current.ParentId == 0)
                {
                    result.Add(node);
                }
            }

            return result.OrderBy(r => r.sortOrder).ToList();
        }

        private MenuResult ConvertToResult(Menu menu)
        {
            return new MenuResult
            {
                Id = menu.Id,
                path = menu.Path,
                name = menu.Name,
                component = menu.Component,
                redirect = menu.Redirect,
                menuType = menu.MenuType,
                sortOrder = menu.SortOrder,
                isActive = menu.IsActive,
                meta = new MetaProps
                {
                    icon = menu.Icon,
                    title = menu.Title,
                    activeMenu = menu.ActiveMenu,
                    isLink = menu.IsLink,
                    isHide = menu.IsHide == 1, // 直接转换为bool
                    isFull = menu.IsFull == 1,
                    isAffix = menu.IsAfix == 1,
                   
                    isKeepAlive = menu.IsKeepAlive == 1
                },
                children = new List<MenuResult>()
            };
        }



        /// <summary>
        /// 更新菜单
        /// </summary>
        public async Task<bool> UpdateAsync(Menu menu)
        {
            // 排除自身的路径校验
            if (await base.Queryable()
                .AnyAsync(m => m.Path == menu.Path && m.Id != menu.Id))
                throw new Exception("路由路径已存在");

            return await base.UpdateAsync(menu);
        }

        /// <summary>
        /// 获取单条菜单
        /// </summary>
        public async Task<Menu> GetByIdAsync(decimal id)
        {
            return await base.Queryable()
                .FirstAsync(m => m.Id == id);
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        public async Task<List<Menu>> GetPagedListAsync(int page, int size, string keyword)
        {
            var query = base.Queryable()
                .WhereIF(!string.IsNullOrEmpty(keyword),
                    m => m.Name.Contains(keyword) || m.Path.Contains(keyword))
                .OrderBy(m => m.SortOrder);

            return await query.ToPageListAsync(page, size);
        }

        /// <summary>
        /// 获取子菜单
        /// </summary>
        public async Task<List<Menu>> GetChildrenAsync(decimal parentId)
        {
            return await base.Queryable()
                .Where(m => m.ParentId == parentId)
                .OrderBy(m => m.SortOrder)
                .ToListAsync();
        }

        /// <summary>
        /// 检查路径是否存在
        /// </summary>
        public async Task<bool> ExistPath(string path, decimal? excludeId = null)
        {
            var query = base.Queryable().Where(m => m.Path == path);
            if (excludeId.HasValue)
                query = query.Where(m => m.Id != excludeId.Value);

            return await query.AnyAsync();
        }
        public int  DeleteList(string[] ids)
        {
          return  _db.Deleteable<Menu>().In(ids).ExecuteCommand();
        }
        public bool EditMenu(Menu menu)
        {
            if (menu.Id <= 0) throw new ArgumentException("无效的菜单ID");

            // 关键修复：将前端传入的 0 转换为 null
            if (menu.ParentId == 0)
            {
                menu.ParentId = null;
            }

            // 父菜单存在性验证
            if (menu.ParentId.HasValue && menu.ParentId.Value > 0)
            {
                // 防止循环引用
                if (menu.ParentId.Value == menu.Id)
                {
                    throw new ArgumentException("不能将菜单设置成自己的父菜单");
                }

                // 验证父菜单存在
                if (!_db.Queryable<Menu>().Any(m => m.Id == menu.ParentId.Value))
                {
                    throw new ArgumentException($"父菜单ID {menu.ParentId} 不存在");
                }
            }

            return _db.Updateable(menu).ExecuteCommand() > 0;
        }
        public bool AddMenu(Menu menu)
        {
            // 转换 0 为 null
            if (menu.ParentId == 0)
            {
                menu.ParentId = null;
            }

            // 父菜单存在性验证
            if (menu.ParentId.HasValue && menu.ParentId.Value > 0)
            {
                // 防止循环引用
                if (menu.ParentId.Value == menu.Id)
                {
                    throw new ArgumentException("不能将菜单设置成自己的父菜单");
                }

                // 验证父菜单存在
                if (!_db.Queryable<Menu>().Any(m => m.Id == menu.ParentId.Value))
                {
                    throw new ArgumentException($"父菜单ID {menu.ParentId} 不存在");
                }
            }

            return _db.Insertable(menu).ExecuteCommand() > 0;
        }

    }
}
